package handler

import (
	pb "bianwang/GetArea/proto"
	"bianwang/web/models"
	"bianwang/web/utils"
	"context"
	"encoding/json"
	"github.com/asim/go-micro/v3/util/log"
	"github.com/beego/beego/v2/client/cache"
	_ "github.com/beego/beego/v2/client/cache/redis"
	"github.com/beego/beego/v2/client/orm"
	"strconv"
	"time"
)

type GetArea struct {
}

// 获取省份信息
func (e *GetArea) GetAreaByProvince(ctx context.Context, req *pb.RequestProvince, rsp *pb.ResponseProvinceData) error {
	utils.AlyLog("---------------- GetArea    api/v1.0/GetAreaByProvince ----------------", "")
	// 初始化返回值
	rsp.Code = utils.RECODE_OK
	rsp.Msg = utils.RecodeText(rsp.Code)

	// 连接redis创建句柄
	redisConfigMap := map[string]string{
		"key":   utils.GlobalConf.AppConfig.Name,
		"conn":  utils.GlobalConf.RedisConfig.Host + ":" + utils.GlobalConf.RedisConfig.Port,
		"dbNum": utils.GlobalConf.RedisConfig.Db,
	}

	// 将map转化为json
	redisConfig, _ := json.Marshal(redisConfigMap)
	// 连接redis
	bm, err := cache.NewCache("redis", string(redisConfig))
	if err != nil {
		utils.AlyLog("缓存创建失败", err.Error())
		rsp.Code = utils.RECODE_REDIS_ERR
		rsp.Msg = utils.RecodeText(rsp.Code)
		return nil
	}
	/*1获取缓存数据*/
	provinceInfoValue, err := bm.Get(context.TODO(), "province_data")
	if provinceInfoValue != nil {
		utils.AlyLog("获取到缓存发送给前端", "")
		//logs.Info("获取到缓存发送给前端")
		// 用来存放解码的json
		//var provinceInfo []models.Province
		var provinceInfo []map[string]interface{}
		// 解码
		err = json.Unmarshal(provinceInfoValue.([]byte), &provinceInfo)

		// 进行循环赋值
		for _, value := range provinceInfo {
			// 创建对于数据类型并进行赋值
			//areaAddress := pb.RequestProvince{{: int32(value["aid"].(float64)), Aname: value["aname"].(string)}}
			areaAddress := pb.Item{
				ParentCode: 0,
				Name:       value["ProvinceName"].(string),
				Code:       int64(value["ProvinceCode"].(float64)),
				ShortName:  value["ShortName"].(string),
				Lng:        value["Lng"].(string),
				Lat:        value["Lat"].(string),
				Sort:       int64(value["Sort"].(float64)),
				Memo:       value["Memo"].(string),
			}
			// 递增到切片
			rsp.Data = append(rsp.Data, &areaAddress)
		}
		return nil
	}
	utils.AlyLog("没有拿到缓存", "")
	/*2 如果没有缓存我们就从mysql 里进行查询 */
	//orm的操作创建orm句柄
	o := orm.NewOrm()

	// 接受地区信息的切片
	var provinces []models.Province

	// 创建查询条件
	qs := o.QueryTable("province")

	num, err := qs.All(&provinces)
	// 查询省份信息
	if err != nil {
		rsp.Code = utils.RECODE_DBERR
		rsp.Msg = utils.RecodeText(rsp.Msg)
		return nil
	}
	if num == 0 {
		rsp.Code = utils.RECODE_NODATA
		rsp.Msg = utils.RecodeText(rsp.Msg)
		return nil
	}

	utils.AlyLog("写入缓存", "")
	/*3 获取数据写入缓存 */

	// 将查询到的数据编码成json格式
	provincesInfoStr, _ := json.Marshal(provinces)
	// Put(key string, val interface{}, timeout time.Duration) error
	// 存入缓存中
	err = bm.Put(context.TODO(), "province_data", provincesInfoStr, time.Second*3600)
	if err != nil {
		utils.AlyLog("数据库中查出数据信息存入缓存中失误", err.Error())
		rsp.Code = utils.RECODE_NODATA
		rsp.Msg = utils.RecodeText(rsp.Msg)
		return nil
	}

	// 返回地区信息
	for _, value := range provinces {
		province := pb.Item{
			ParentCode: 0,
			Name:       value.ProvinceName,
			Code:       int64(value.ProvinceCode),
			ShortName:  value.ShortName,
			Lng:        value.Lng,
			Lat:        value.Lng,
			Sort:       int64(value.Sort),
			Memo:       value.Memo,
		}
		rsp.Data = append(rsp.Data, &province)
	}
	return nil
}

// 获取城市信息
func (e *GetArea) GetAreaByCity(ctx context.Context, req *pb.RequestCity, rsp *pb.ResponseCityData) error {
	utils.AlyLog("---------------- GetArea    api/v1.0/GetAreaByCity ----------------", "")
	// 初始化返回值
	rsp.Code = utils.RECODE_OK
	rsp.Msg = utils.RecodeText(rsp.Code)

	// 连接redis创建句柄
	redisConfigMap := map[string]string{
		"key":   utils.GlobalConf.AppConfig.Name,
		"conn":  utils.GlobalConf.RedisConfig.Host + ":" + utils.GlobalConf.RedisConfig.Port,
		"dbNum": utils.GlobalConf.RedisConfig.Db,
	}

	// 将map转化为json
	redisConfig, _ := json.Marshal(redisConfigMap)

	// 连接redis
	bm, err := cache.NewCache("redis", string(redisConfig))
	if err != nil {
		utils.AlyLog("缓存创建失败", err.Error())
		rsp.Code = utils.RECODE_DBERR
		rsp.Msg = utils.RecodeText(rsp.Msg)
		return nil
	}
	/*1获取缓存数据*/
	CityInfoValue, err := bm.Get(context.TODO(), "city_data")
	if CityInfoValue != nil {
		utils.AlyLog("获取到缓存发送给前端", "")
		// 用来存放解码的json
		var cityInfo []map[string]interface{}
		// 解码
		err = json.Unmarshal(CityInfoValue.([]byte), &cityInfo)
		// 进行循环赋值
		for _, value := range cityInfo {
			// 创建对于数据类型并进行赋值
			areaAddress := pb.Item{
				ParentCode: int64(value["ProvinceCode"].(float64)),
				Name:       value["CityName"].(string),
				Code:       int64(value["CityCode"].(float64)),
				ShortName:  value["ShortName"].(string),
				Lng:        value["Lng"].(string),
				Lat:        value["Lat"].(string),
				Sort:       int64(value["Sort"].(float64)),
				Memo:       value["Memo"].(string),
			}
			// 递增到切片
			rsp.Data = append(rsp.Data, &areaAddress)
		}
		return nil
	}
	utils.AlyLog("没有拿到缓存", "")
	/*2 如果没有缓存我们就从mysql 里进行查询 */
	//orm的操作创建orm句柄
	o := orm.NewOrm()

	// 接受地区信息的切片
	var citys []models.City

	// 创建查询条件
	qs := o.QueryTable("city")
	if req.Code != 0 {
		qs = qs.Filter("province_code", req.Code)
	}
	num, err := qs.All(&citys)
	// 查询城市信息
	if err != nil {
		rsp.Code = utils.RECODE_DBERR
		rsp.Msg = utils.RecodeText(rsp.Msg)
		return nil
	}
	if num == 0 {
		rsp.Code = utils.RECODE_NODATA
		rsp.Msg = utils.RecodeText(rsp.Msg)
		return nil
	}

	utils.AlyLog("写入缓存", "")
	/*3 获取数据写入缓存 */

	// 将查询到的数据编码成json格式
	citysInfoStr, _ := json.Marshal(citys)
	// Put(key string, val interface{}, timeout time.Duration) error
	// 存入缓存中
	err = bm.Put(context.TODO(), "city_data", citysInfoStr, time.Second*3600)
	if err != nil {
		utils.AlyLog("数据库中查出数据信息存入缓存中失误", err.Error())
		rsp.Code = utils.RECODE_NODATA
		rsp.Msg = utils.RecodeText(rsp.Msg)
		return nil
	}

	// 返回地区信息
	for _, value := range citys {
		city := pb.Item{
			ParentCode: value.ProvinceCode,
			Name:       value.CityName,
			Code:       value.CityCode,
			ShortName:  value.ShortName,
			Lng:        value.Lng,
			Lat:        value.Lng,
			Sort:       int64(value.Sort),
			Memo:       value.Memo,
		}
		rsp.Data = append(rsp.Data, &city)
	}
	return nil
}

// 获取区域信息
func (e *GetArea) GetAreaByArea(ctx context.Context, req *pb.RequestArea, rsp *pb.ResponseAreaData) error {
	utils.AlyLog("---------------- GetArea    api/v1.0/area/GetAreaByArea ----------------", "")
	// 初始化返回值
	rsp.Code = utils.RECODE_OK
	rsp.Msg = utils.RecodeText(rsp.Code)

	// 连接redis创建句柄
	redisConfigMap := map[string]string{
		"key":   utils.GlobalConf.AppConfig.Name,
		"conn":  utils.GlobalConf.RedisConfig.Host + ":" + utils.GlobalConf.RedisConfig.Port,
		"dbNum": utils.GlobalConf.RedisConfig.Db,
	}

	// 将map转化为json
	redisConfig, _ := json.Marshal(redisConfigMap)
	// 连接redis
	bm, err := cache.NewCache("redis", string(redisConfig))
	if err != nil {
		utils.AlyLog("缓存创建失败", err.Error())
		rsp.Code = utils.RECODE_DBERR
		rsp.Msg = utils.RecodeText(rsp.Msg)
		return nil
	}
	/*1获取缓存数据*/
	AreaInfoValue, err := bm.Get(context.TODO(), "area_data")
	if AreaInfoValue != nil {
		utils.AlyLog("获取到缓存发送给前端", "")
		// 用来存放解码的json
		var areaInfo []map[string]interface{}
		// 解码
		err = json.Unmarshal(AreaInfoValue.([]byte), &areaInfo)
		// 进行循环赋值
		for _, value := range areaInfo {
			// 创建对于数据类型并进行赋值
			areaAddress := pb.Item{
				ParentCode: int64(value["CityCode"].(float64)),
				Name:       value["AreaName"].(string),
				Code:       int64(value["AreaCode"].(float64)),
				ShortName:  value["ShortName"].(string),
				Lng:        value["Lng"].(string),
				Lat:        value["Lat"].(string),
				Sort:       int64(value["Sort"].(float64)),
				Memo:       value["Memo"].(string),
			}
			// 递增到切片
			rsp.Data = append(rsp.Data, &areaAddress)
		}
		return nil
	}
	utils.AlyLog("没有拿到缓存", "")
	/*2 如果没有缓存我们就从mysql 里进行查询 */
	//orm的操作创建orm句柄
	o := orm.NewOrm()

	// 接受地区信息的切片
	var areas []models.Area

	// 创建查询条件
	qs := o.QueryTable("area")

	if req.Code != 0 {
		qs = qs.Filter("city_code", req.Code)
	}
	num, err := qs.All(&areas)
	// 查询城市信息
	if err != nil {
		rsp.Code = utils.RECODE_DBERR
		rsp.Msg = utils.RecodeText(rsp.Msg)
		return nil
	}
	if num == 0 {
		rsp.Code = utils.RECODE_NODATA
		rsp.Msg = utils.RecodeText(rsp.Msg)
		return nil
	}

	utils.AlyLog("写入缓存", "")
	/*3 获取数据写入缓存 */

	// 将查询到的数据编码成json格式
	areasInfoStr, _ := json.Marshal(areas)
	// Put(key string, val interface{}, timeout time.Duration) error
	// 存入缓存中
	err = bm.Put(context.TODO(), "area_data", areasInfoStr, time.Second*3600)
	if err != nil {
		utils.AlyLog("数据库中查出数据信息存入缓存中失误", err.Error())
		rsp.Code = utils.RECODE_NODATA
		rsp.Msg = utils.RecodeText(rsp.Msg)
		return nil
	}

	// 返回地区信息
	for _, value := range areas {
		area := pb.Item{
			ParentCode: value.CityCode,
			Name:       value.AreaName,
			Code:       value.AreaCode,
			ShortName:  value.ShortName,
			Lng:        value.Lng,
			Lat:        value.Lng,
			Sort:       int64(value.Sort),
			Memo:       value.Memo,
		}
		rsp.Data = append(rsp.Data, &area)
	}
	return nil
}

// 获取街道信息
func (e *GetArea) GetAreaByStreet(ctx context.Context, req *pb.RequestStreet, rsp *pb.ResponseStreetData) error {
	utils.AlyLog("---------------- GetArea    api/v1.0/area/GetAreaByStreet ----------------", "")
	// 初始化返回值
	rsp.Code = utils.RECODE_OK
	rsp.Msg = utils.RecodeText(rsp.Code)

	// 连接redis创建句柄
	redisConfigMap := map[string]string{
		"key":   utils.GlobalConf.AppConfig.Name,
		"conn":  utils.GlobalConf.RedisConfig.Host + ":" + utils.GlobalConf.RedisConfig.Port,
		"dbNum": utils.GlobalConf.RedisConfig.Db,
	}

	// 将map转化为json
	redisConfig, _ := json.Marshal(redisConfigMap)
	// 连接redis
	bm, err := cache.NewCache("redis", string(redisConfig))
	if err != nil {
		utils.AlyLog("缓存创建失败", err.Error())
		rsp.Code = utils.RECODE_DBERR
		rsp.Msg = utils.RecodeText(rsp.Msg)
		return nil
	}
	/*1获取缓存数据*/
	StreetInfoValue, err := bm.Get(context.TODO(), "street_data")
	if StreetInfoValue != nil {
		utils.AlyLog("获取到缓存发送给前端", "")
		// 用来存放解码的json
		var streetInfo []map[string]interface{}
		// 解码
		err = json.Unmarshal(StreetInfoValue.([]byte), &streetInfo)
		// 进行循环赋值
		for _, value := range streetInfo {
			// 创建对于数据类型并进行赋值
			streetAddress := pb.Item{
				ParentCode: int64(value["ParentCode"].(float64)),
				Name:       value["StreetName"].(string),
				Code:       int64(value["AreaCode"].(float64)),
				ShortName:  value["ShortName"].(string),
				Lng:        value["Lng"].(string),
				Lat:        value["Lat"].(string),
				Sort:       int64(value["Sort"].(float64)),
				Memo:       value["Memo"].(string),
			}
			// 递增到切片
			rsp.Data = append(rsp.Data, &streetAddress)
		}
		return nil
	}
	utils.AlyLog("没有拿到缓存", "")
	/*2 如果没有缓存我们就从mysql 里进行查询 */
	//orm的操作创建orm句柄
	o := orm.NewOrm()

	// 接受地区信息的切片
	var streets []models.Street

	// 创建查询条件
	qs := o.QueryTable("street")
	if req.Code != 0 {
		qs = qs.Filter("area_code", req.Code)
	}
	num, err := qs.All(&streets)
	// 查询城市信息
	if err != nil {
		rsp.Code = utils.RECODE_DBERR
		rsp.Msg = utils.RecodeText(rsp.Msg)
		return nil
	}
	if num == 0 {
		rsp.Code = utils.RECODE_NODATA
		rsp.Msg = utils.RecodeText(rsp.Msg)
		return nil
	}

	utils.AlyLog("写入缓存", "")
	/*3 获取数据写入缓存 */

	// 将查询到的数据编码成json格式
	streetsInfoStr, _ := json.Marshal(streets)
	// Put(key string, val interface{}, timeout time.Duration) error
	// 存入缓存中
	err = bm.Put(context.TODO(), "streets_data", streetsInfoStr, time.Second*3600)
	if err != nil {
		utils.AlyLog("数据库中查出数据信息存入缓存中失误", err.Error())
		rsp.Code = utils.RECODE_NODATA
		rsp.Msg = utils.RecodeText(rsp.Msg)
		return nil
	}

	// 返回地区信息
	for _, value := range streets {
		street := pb.Item{
			ParentCode: value.AreaCode,
			Name:       value.StreetName,
			Code:       value.StreetCode,
			ShortName:  value.ShortName,
			Lng:        value.Lng,
			Lat:        value.Lng,
			Sort:       int64(value.Sort),
			Memo:       value.Memo,
		}
		rsp.Data = append(rsp.Data, &street)
	}
	return nil
}

// 获取全部城市街道信息
func (e *GetArea) GetAreas(ctx context.Context, req *pb.Request, rsp *pb.Response) error {
	utils.AlyLog("---------------- GetArea    api/v1.0/area/GetAreas ----------------", "")

	code := req.Code
	level := req.Level
	// 初始化返回值
	rsp.Code = utils.RECODE_OK
	rsp.Msg = utils.RecodeText(rsp.Code)

	// 连接redis创建句柄
	redisConfigMap := map[string]string{
		"key":   utils.GlobalConf.AppConfig.Name,
		"conn":  utils.GlobalConf.RedisConfig.Host + ":" + utils.GlobalConf.RedisConfig.Port,
		"dbNum": utils.GlobalConf.RedisConfig.Db,
	}

	// 将map转化为json
	redisConfig, _ := json.Marshal(redisConfigMap)

	// 连接redis
	bm, err := cache.NewCache("redis", string(redisConfig))
	if err != nil {
		utils.AlyLog("redis缓存链接创建失败", err.Error())
		rsp.Code = utils.RECODE_REDIS_ERR
		rsp.Msg = utils.RecodeText(rsp.Code)
		return nil
	}

	// 创建orm句柄
	o := orm.NewOrm()

	/*1获取省份信息数据*/
	var provinces []models.Province
	GetAreasProvice, _ := bm.Get(context.TODO(), "GetAreasProvice"+strconv.FormatInt(code, 10))
	// 如果缓存信息存在
	if GetAreasProvice != nil {
		_ = json.Unmarshal(GetAreasProvice.([]byte), &provinces)
	} else {
		// 查找省份信息
		qp := o.QueryTable("province")
		if code != 0 {
			qp = qp.Filter("province_code", code)
		}
		num, err := qp.All(&provinces)

		if err != nil {
			utils.AlyLog("---------------- 省份信息查询失败1 <查询条件>----------------", strconv.FormatInt(code, 10))
			rsp.Code = utils.RECODE_AREA_PROVINCE
			rsp.Msg = utils.RecodeText(rsp.Code)
			return nil
		}
		if num == 0 {
			utils.AlyLog("---------------- 省份信息查询失败2 <查询条件>----------------", strconv.FormatInt(code, 10))
			rsp.Code = utils.RECODE_AREA_PROVINCE
			rsp.Msg = utils.RecodeText(rsp.Code)
			return nil
		}

		// 存入缓存中
		provincesInfoStr, _ := json.Marshal(&provinces)
		// Put(key string, val interface{}, timeout time.Duration) error
		err = bm.Put(context.TODO(), "GetAreasProvice"+strconv.FormatInt(code, 10), provincesInfoStr, time.Second*3600)
		if err != nil {
			utils.AlyLog("---------------- 省份信息查询失败3 <redis入缓存>----------------", err.Error())
			utils.AlyLog("数据库中查出省份信息存入缓存中失误", err.Error())
			rsp.Code = utils.RECODE_AREA_PROVINCE
			rsp.Msg = utils.RecodeText(rsp.Code)
			return nil
		}

	}

	/*2获取城市信息数据*/
	//var cityData make([]models.City)
	cityData := make(map[int64][]models.City)
	//所有查询出得城市id
	var searchCity []int64

	if level >= 2 {
		GetAreasCity, _ := bm.Get(context.TODO(), "GetAreasCity"+strconv.FormatInt(code, 10))
		// 如果缓存信息存在
		if GetAreasCity != nil {
			_ = json.Unmarshal(GetAreasCity.([]byte), &cityData)
		} else {
			// 查找省份信息
			var citys []models.City
			qc := o.QueryTable("city")
			if code != 0 {
				qc = qc.Filter("province_code", code)
			}
			num, err := qc.All(&citys)
			if err != nil {
				utils.AlyLog("---------------- 城市信息查询失败1 <查询条件>----------------", strconv.FormatInt(code, 10))
				rsp.Code = utils.RECODE_PARAMERR
				rsp.Msg = utils.RecodeText(rsp.Code)
				return nil
			}
			if num == 0 {
				utils.AlyLog("---------------- 城市信息查询失败2 <查询条件>----------------", strconv.FormatInt(code, 10))

				rsp.Code = utils.RECODE_NODATA
				rsp.Msg = utils.RecodeText(rsp.Code)
				return nil
			}

			//处理城市数据
			//var cityData map[int64][]models.City
			for _, CityDatasItem := range citys {
				searchCity = append(searchCity, CityDatasItem.CityCode)
				cityData[CityDatasItem.ProvinceCode] = append(cityData[CityDatasItem.ProvinceCode], CityDatasItem)
			}
			// 将查询到的数据编码成json格式
			// 存入缓存中
			cityDataInfoStr, _ := json.Marshal(cityData)
			// Put(key string, val interface{}, timeout time.Duration) error
			err = bm.Put(context.TODO(), "GetAreasCity"+strconv.FormatInt(code, 10), cityDataInfoStr, time.Second*3600)
			if err != nil {
				utils.AlyLog("---------------- 城市信息查询失败3 <redis入缓存>----------------", err.Error())
				rsp.Code = utils.RECODE_NODATA
				rsp.Msg = utils.RecodeText(rsp.Msg)
				return nil
			}

		}
	}

	/*3 从缓存里查询城市区域信息 */
	//var areaData map[int64][]models.Area
	areaData := make(map[int64][]models.Area)
	var searchArea []int64
	if level >= 3 {
		GetAreasAreas, _ := bm.Get(context.TODO(), "GetAreasAreas"+strconv.FormatInt(code, 10))
		// 如果缓存信息存在
		if GetAreasAreas != nil {
			_ = json.Unmarshal(GetAreasAreas.([]byte), &areaData)
		} else {
			// 查找省份信息
			var areas []models.Area
			qa := o.QueryTable("area")
			if len(searchCity) > 0 {
				qa = qa.Filter("city_code__in", searchCity)
			}
			num, err := qa.All(&areas)

			if err != nil {
				utils.AlyLog("---------------- 区域信息查询失败1 <查询条件>----------------", strconv.FormatInt(code, 10))
				rsp.Code = utils.RECODE_PARAMERR
				rsp.Msg = utils.RecodeText(rsp.Code)
				return nil
			}
			if num == 0 {
				utils.AlyLog("---------------- 区域信息查询失败2 <查询条件>----------------", strconv.FormatInt(code, 10))
				rsp.Code = utils.RECODE_NODATA
				rsp.Msg = utils.RecodeText(rsp.Code)
				return nil
			}

			//处理城市区域数据
			//var cityData map[int64][]models.City
			for _, areaDatasItem := range areas {
				searchArea = append(searchArea, areaDatasItem.AreaCode)
				areaData[areaDatasItem.CityCode] = append(areaData[areaDatasItem.CityCode], areaDatasItem)
			}

			// 将查询到的数据编码成json格式
			// 存入缓存中
			areaDataInfoStr, _ := json.Marshal(areaData)
			// Put(key string, val interface{}, timeout time.Duration) error
			err = bm.Put(context.TODO(), "GetAreasAreas"+strconv.FormatInt(code, 10), areaDataInfoStr, time.Second*3600)
			if err != nil {
				utils.AlyLog("---------------- 区域信息查询失败3 <redis入缓存>----------------", err.Error())
				rsp.Code = utils.RECODE_NODATA
				rsp.Msg = utils.RecodeText(rsp.Msg)
				return nil
			}
		}
	}

	/*4 从缓存里查询街道信息 */
	//var streetData map[int64][]models.Street
	streetData := make(map[int64][]models.Street)

	if level >= 4 {
		GetAreasStreets, _ := bm.Get(context.TODO(), "GetAreasStreets"+strconv.FormatInt(code, 10))
		// 如果缓存信息存在
		if GetAreasStreets != nil {
			_ = json.Unmarshal(GetAreasStreets.([]byte), &streetData)
		} else {
			// 查找省份信息
			var streets []models.Street
			qs := o.QueryTable("street")
			if len(searchArea) > 0 {
				qs = qs.Filter("area_code__in", searchArea)
			}
			num, err := qs.All(&streets)

			if err != nil {
				utils.AlyLog("---------------- 街道信息查询失败1 <查询条件>----------------", strconv.FormatInt(code, 10))
				rsp.Code = utils.RECODE_PARAMERR
				rsp.Msg = utils.RecodeText(rsp.Code)
				return nil
			}
			if num == 0 {
				utils.AlyLog("---------------- 街道信息查询失败2 <查询条件>----------------", strconv.FormatInt(code, 10))
				rsp.Code = utils.RECODE_NODATA
				rsp.Msg = utils.RecodeText(rsp.Code)
				return nil
			}

			//处理街道数据
			for _, atreetDatasItem := range streets {
				streetData[atreetDatasItem.AreaCode] = append(streetData[atreetDatasItem.AreaCode], atreetDatasItem)
			}

			// 将查询到的数据编码成json格式
			// 存入缓存中
			streetsInfoStr, _ := json.Marshal(streetData)
			// Put(key string, val interface{}, timeout time.Duration) error
			err = bm.Put(context.TODO(), "GetAreasStreets"+strconv.FormatInt(code, 10), streetsInfoStr, time.Second*3600)
			if err != nil {
				utils.AlyLog("---------------- 街道信息查询失败3 <redis入缓存>----------------", err.Error())
				rsp.Code = utils.RECODE_NODATA
				rsp.Msg = utils.RecodeText(rsp.Msg)
				return nil
			}
		}
	}

	//已经取到所有元数据,对元数据进行处理

	// 返回地区信息
	for _, valueProvince := range provinces {

		//匹配城市信息
		var CityData []*pb.Response_ItemTwo
		for _, CityDatasValue := range cityData[valueProvince.ProvinceCode] {

			//匹配区域信息
			var AreaData []*pb.Response_ItemThree
			for _, AreaDatasValue := range areaData[CityDatasValue.CityCode] {

				//匹配村县信息
				var StreetData []*pb.Item
				for _, StreetDatasValue := range streetData[AreaDatasValue.AreaCode] {
					StreetDataInfo := pb.Item{
						ParentCode: StreetDatasValue.AreaCode,
						Name:       StreetDatasValue.StreetName,
						Code:       StreetDatasValue.StreetCode,
						ShortName:  StreetDatasValue.ShortName,
						Lng:        StreetDatasValue.Lng,
						Lat:        StreetDatasValue.Lat,
						Sort:       StreetDatasValue.Sort,
						Memo:       StreetDatasValue.Memo,
					}
					StreetData = append(StreetData, &StreetDataInfo)
				}
				AreaDataInfo := pb.Response_ItemThree{
					ParentCode: AreaDatasValue.CityCode,
					Name:       AreaDatasValue.AreaName,
					Code:       AreaDatasValue.AreaCode,
					ShortName:  AreaDatasValue.ShortName,
					Lng:        AreaDatasValue.Lng,
					Lat:        AreaDatasValue.Lat,
					Sort:       AreaDatasValue.Sort,
					Memo:       AreaDatasValue.Memo,
					Data:       StreetData,
				}
				AreaData = append(AreaData, &AreaDataInfo)
			}

			CityDataInfo := pb.Response_ItemTwo{
				ParentCode: CityDatasValue.ProvinceCode,
				Name:       CityDatasValue.CityName,
				Code:       CityDatasValue.CityCode,
				ShortName:  CityDatasValue.ShortName,
				Lng:        CityDatasValue.Lng,
				Lat:        CityDatasValue.Lat,
				Sort:       CityDatasValue.Sort,
				Memo:       CityDatasValue.Memo,
				Data:       AreaData,
			}
			CityData = append(CityData, &CityDataInfo)

		}

		//获取省份信息
		ProvinceData := pb.Response_ItemData{
			ParentCode: 0,
			Name:       valueProvince.ProvinceName,
			Code:       valueProvince.ProvinceCode,
			ShortName:  valueProvince.ShortName,
			Lng:        valueProvince.Lng,
			Lat:        valueProvince.Lng,
			Sort:       int64(valueProvince.Sort),
			Memo:       valueProvince.Memo,
			Data:       CityData,
		}
		rsp.Data = append(rsp.Data, &ProvinceData)
	}
	return nil
}

// Stream is a server side stream handler called via client.Stream or the generated client code
func (e *GetArea) Stream(ctx context.Context, req *pb.StreamingRequest, stream pb.GetArea_StreamStream) error {
	log.Logf("Received Example.Stream request with count: %d", req.Count)

	for i := 0; i < int(req.Count); i++ {
		log.Logf("Responding: %d", i)
		if err := stream.Send(&pb.StreamingResponse{
			Count: int64(i),
		}); err != nil {
			return err
		}
	}
	return nil
}

// PingPong is a bidirectional stream handler called via client.Stream or the generated client code
func (e *GetArea) PingPong(ctx context.Context, stream pb.GetArea_PingPongStream) error {
	for {
		req, err := stream.Recv()
		if err != nil {
			return err
		}
		log.Logf("Got ping %v", req.Stroke)
		if err := stream.Send(&pb.Pong{Stroke: req.Stroke}); err != nil {
			return err
		}
	}
}
